package com.shitou.springai1.admin.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.shitou.springai1.admin.entity.dto.FileDto;
import com.shitou.springai1.admin.entity.vo.FileVo;
import com.shitou.springai1.admin.mapper.FileMapper;
import com.shitou.springai1.admin.service.FileService;
import com.shitou.springai1.user.service.RedisVectorStoreService;
import lombok.RequiredArgsConstructor;
import org.springframework.ai.document.Document;
import org.springframework.ai.vectorstore.redis.RedisVectorStore;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 文件服务实现类
 */
@Service
@RequiredArgsConstructor
public class FileServiceImpl extends ServiceImpl<FileMapper, FileDto> implements FileService {

    private final FileMapper fileMapper;
    @Autowired
    private RedisVectorStore redisVectorStore;

    private static final String FILE_STORAGE_PATH = "src/main/resources/static/files/";
    private static final int CHUNK_SIZE = 1000; // 分片大小，可根据需要调整

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean saveFile(FileDto fileDto) {
        // 为文件生成唯一ID
        String fileId = UUID.randomUUID().toString();
        fileDto.setFileId(fileId);
        fileDto.setCreateTime(LocalDate.now());
        fileDto.setUpdateTime(LocalDate.now());
        
        // 保存文件信息到数据库
        return this.save(fileDto);
    }

    @Override
    public List<Map<String, Object>> getFiles(int pageNum, int pageSize, String keyword) {
        // 分页查询文件
        if (pageNum < 1) pageNum = 1;
        if (pageSize < 1 || pageSize > 100) pageSize = 6;
        Page<FileDto> page = new Page<>(pageNum, pageSize);

        // 构建查询条件
        QueryWrapper<FileDto> queryWrapper = null;
        if (keyword != null && !keyword.trim().isEmpty()) {
            queryWrapper = new QueryWrapper<FileDto>()
                    .like("file_name", keyword.trim())
                    .or()
                    .like("file_id", keyword.trim());
        }

        // 执行分页查询
        Page<FileDto> fileDtoPage = fileMapper.selectPage(page, queryWrapper);
        List<FileDto> fileDtos = fileDtoPage.getRecords();

        // 转换为Map列表
        return fileDtos.stream().map(fileDto -> {
            Map<String, Object> map = new HashMap<>();
            map.put("id", fileDto.getId());
            map.put("fileId", fileDto.getFileId() == null ? "" : fileDto.getFileId());
            map.put("fileName", fileDto.getFileName() == null ? "" : fileDto.getFileName());
            map.put("fileUrl", fileDto.getFileUrl() == null ? "" : fileDto.getFileUrl());
            map.put("createTime", fileDto.getCreateTime());
            map.put("updateTime", fileDto.getUpdateTime());
            return map;
        }).collect(Collectors.toList());
    }

    @Override
    public FileDto getByFileId(String fileId) {
        QueryWrapper<FileDto> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("file_id", fileId);
        return fileMapper.selectOne(queryWrapper);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteFile(Long id) {
        // 先查询文件信息
        FileDto fileDto = this.getById(id);
        if (fileDto != null) {
            // 删除数据库记录
            return this.removeById(id);
        }
        return false;
    }

    @Override
    public List<Document> processAndStoreFileToVectorStore(FileDto fileDto, String fileContent) {
        List<Document> documents = new ArrayList<>();
        
        try {
            // 对文件内容进行分片处理
            List<String> chunks = splitContentIntoChunks(fileContent, CHUNK_SIZE);
            
            // 为每个分片创建Document并添加元数据
            for (int i = 0; i < chunks.size(); i++) {
                Map<String, Object> metadata = new HashMap<>();
                metadata.put("fileId", fileDto.getFileId());
                metadata.put("fileName", fileDto.getFileName());
                metadata.put("chunkIndex", i);
                metadata.put("totalChunks", chunks.size());
                
                Document document = new Document(chunks.get(i), metadata);
                documents.add(document);
            }
            
            // 存储到向量数据库
            if (!documents.isEmpty()) {
                redisVectorStore.add(documents);
            }
            
        } catch (Exception e) {
            log.error("处理文件并存储到向量数据库失败", e);
        }
        
        return documents;
    }

    /**
     * 将内容分割成指定大小的片段
     */
    private List<String> splitContentIntoChunks(String content, int chunkSize) {
        List<String> chunks = new ArrayList<>();
        
        if (content == null || content.isEmpty()) {
            return chunks;
        }
        
        // 针对不同类型的文件进行不同的处理逻辑
        // 这里简化处理，直接按字符数分片
        int length = content.length();
        for (int i = 0; i < length; i += chunkSize) {
            int end = Math.min(i + chunkSize, length);
            // 尽量在句子结束处分割，以保持语义完整性
            if (end < length) {
                int lastPeriodIndex = content.lastIndexOf(".", end);
                int lastCommaIndex = content.lastIndexOf(",", end);
                int lastSpaceIndex = content.lastIndexOf(" ", end);
                
                int bestSplitIndex = Math.max(Math.max(lastPeriodIndex, lastCommaIndex), lastSpaceIndex);
                if (bestSplitIndex > i) {
                    end = bestSplitIndex + 1; // 包含分隔符
                }
            }
            chunks.add(content.substring(i, end).trim());
        }
        
        return chunks;
    }

    // 添加日志记录功能
    private void log(String message) {
        System.out.println("[FileService] " + message);
    }
}
